package com.liting.uitest.imgutils;

import com.liting.uitest.model.Circle;
import com.liting.uitest.model.ImageInfo;
import com.liting.uitest.model.Rectangle;
import com.liting.uitest.service.impl.ImageCacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashSet;
import java.util.List;

/**
 * 整体感计算
 */
@Service
public class UNCalc {
    @Autowired
    private ImageCacheService cacheService;

    public BigDecimal unCalc(Long fileId, List<Rectangle> rectList, List<Circle> cirList) throws Exception {
        ImageInfo imageInfo = cacheService.getImage(fileId);
        if (imageInfo == null) {
            throw new Exception("文件不存在");
        }


        BigDecimal unForm = unFormCalc(rectList, cirList);
        BigDecimal unSpace = unSpace(imageInfo, rectList, cirList);
        return unForm.add(unSpace).divide(new BigDecimal(2)).setScale(1, RoundingMode.UP);
    }

    private BigDecimal unSpace(ImageInfo imageInfo, List<Rectangle> rectList, List<Circle> cirList) {
        Rectangle outRect = createOutRect(rectList, cirList);

        BigDecimal allArea = new BigDecimal(0);
        for (Rectangle rectangle : rectList) {
            allArea = allArea.add(rectangle.getArea());
        }

        for (Circle circle : cirList) {
            allArea = allArea.add(circle.getArea());
        }

        BigDecimal temp1 = outRect.getArea().subtract(allArea);
        BigDecimal temp2 = new BigDecimal(imageInfo.getWidth()).multiply(new BigDecimal(imageInfo.getHeight())).subtract(allArea);

        return new BigDecimal(1).subtract(temp1.divide(temp2, BigDecimal.ROUND_HALF_UP));
    }

    //生成所有元素的外接矩形
    private Rectangle createOutRect(List<Rectangle> rectList, List<Circle> cirList) {
        double minLeft = Integer.MAX_VALUE, minTop = Integer.MAX_VALUE, maxRight = 0, maxButtom = 0;

        for (Rectangle rectangle : rectList) {
            if (rectangle.getLeftTopX() < minLeft) minLeft = rectangle.getLeftTopX();
            if (rectangle.getLeftTopY() < minTop) minTop = rectangle.getLeftTopY();

            double rightButtomX = rectangle.getLeftTopX() + rectangle.getWidth();
            double rightButtomY = rectangle.getLeftTopY() + rectangle.getHeight();
            if (rightButtomX > maxRight) maxRight = rightButtomX;
            if (rightButtomY > maxButtom) maxButtom = rightButtomY;
        }

        for (Circle circle : cirList) {
            double leftMinX = circle.getCenterX() - circle.getRadius();
            double topMinY = circle.getCenterY() - circle.getRadius();
            double rightMaxX = circle.getCenterX() + circle.getRadius();
            double buttomMaxY = circle.getCenterY() + circle.getRadius();

            if (leftMinX < minLeft) minLeft = leftMinX;
            if (topMinY < minTop) minTop = topMinY;
            if (rightMaxX > maxRight) maxRight = rightMaxX;
            if (buttomMaxY > maxButtom) maxButtom = buttomMaxY;
        }

        Rectangle outRect = new Rectangle();
        outRect.setLeftTopX(minLeft);
        outRect.setLeftTopY(minTop);
        outRect.setWidth(maxRight - minLeft);
        outRect.setHeight(maxButtom - minTop);

        return outRect;
    }

    private int notSameCirCount(List<Circle> cirList) {
        return new HashSet<Object>(cirList).size();
    }

    private int notSameRectCount(List<Rectangle> rectList) {
        return new HashSet<Object>(rectList).size();
    }

    private BigDecimal unFormCalc(List<Rectangle> rectList, List<Circle> cirList) {
        int notSameCount1 = notSameRectCount(rectList);
        int notSameCount2 = notSameCirCount(cirList);
        int temp = notSameCount1 + notSameCount2 - 1;
        int allCount = rectList.size() + cirList.size();

        BigDecimal result = new BigDecimal(1).subtract(new BigDecimal(temp).divide(new BigDecimal(allCount), BigDecimal.ROUND_HALF_UP));
        return result;
    }
}
